module Data.Graph.IntegrationQuickCheck where

import Data.Graph.Integration
import Data.Graph.Slicing
import Data.Graph.Components (weakComponents)
import Test.QuickCheck
import Data.Relation.SetOfPairs
import Data.Set as Set
import Data.Relation.SetOfPairsQuickCheck ()


prop_IntegrateNoInterferenceBothEmpty r
  = classify (Set.size r /= 0) "non-empty" $
    classify connected "connected" $
    (ok && m==emptyRel)
    where
      (m,ok) = integrate emptyRel emptyRel r
      connected = length (weakComponents r) == 1
      types = (r::Rel Int Int)

prop_IntegrateNoInterferenceBaseEmptyBothEqual r
  = classify (Set.size r /= 0) "non-empty" $
    classify connected "connected" $
    (ok && m==r)
    where
      (m,ok) = integrate r r emptyRel
      connected = length (weakComponents r) == 1
      types = (r::Rel Int Int)

prop_IntegrateNoInterferenceOneEmpty r
  = classify (Set.size r /= 0) "non-empty" $
    classify connected "connected" $
    (ok && m==emptyRel)
    where
      (m,ok) = integrate emptyRel r r
      connected = length (weakComponents r) == 1
      types = (r::Rel Int Int)

prop_IntegrateNoInterferenceOneNonEmpty r
  = classify (Set.size r /= 0) "non-empty" $
    classify connected "connected" $
    (ok && m==r)
    where
      (m,ok) = integrate emptyRel r emptyRel
      connected = length (weakComponents r) == 1
      types = (r::Rel Int Int)

prop_IntegrateNoInterferenceSliceOfBase s r
  = classify (Set.size r /= 0) "non-empty" $
    classify connected "connected" $
    (ok && m==r')
    where
      r' = slice s r
      (m,ok) = integrate r' r r
      connected = length (weakComponents r) == 1
      types = (r::Rel Int Int)

prop_IntegrateNoInterferenceSliceOfOne s r
  = classify (Set.size r /= 0) "non-empty" $
    classify connected "connected" $
    (ok && m==r)
    where
      r' = slice s r
      (m,ok) = integrate r r' r'
      connected = length (weakComponents r) == 1
      types = (r::Rel Int Int)

prop_IntegratePreservedpoints a b base
  = --classify allEmpty "all empty" $
    classify (not allEmpty) "not all empty" $
    classify ok "no interference" $
    if ok then m//pp == base//pp else True
    where
      allEmpty = Set.size (a`union`b`union`base`union`m) == 0
      (m,ok) = integrate a b base
      pp = preservedPoints a b base
      g // s = sliceBackward s g
      types = (a::Rel Int Int)


